function playlist(Player){
	
	var Entities = [];
	var CurrMode = "repeatAll";
	var Pos = 0;
	var SelectedPos = 0;	
	var timer = null;
	var self  = this;
	/**
	 * in den modes dÃ¼rfen wir jetzt nichmehr CORE.Player.stop() etc machen 
	 * nurnoch die pos ermitteln und zurÃ¼ckgeben (immer von der jetztigen ausgehend)
	 */
	var Modes = {
			next: function(r){
				if(r){
					//reverse
					if(Pos-1 < 0){
						return -1;
					}else{
						return (Pos-1)*1;
					}
				}else{//not reverse
					if(Pos+1 > Entities.length-1){
						return -1;
					}else{
						return (Pos+1)*1;
					}
				}
				
			},
			shuffle: function(r){
				//shuffle blabla
			},
			repeatAll: function(r){
				if(r){
					//reverse
					if(Pos-1 < 0){
						return Entities.length-1;
						//am ende
					}else{
						return (Pos-1)*1;
					}
				}else{//not reverse
					//console.log(Pos);  //self.parent??
					if(Pos+1 > Entities.length-1){
						return 0;
						//am ende
					}else{
						return (Pos+1)*1;
					}
				}
			}
	};

	
	this.init = function(){
		CORE.Input.attach("onDropFile", this.onDropFile);
		CORE.Input.attach("onClickPlaylistItem", this.onClickPlaylistItem);
		CORE.Input.attach("onDblClickPlaylistItem", this.onDblClickPlaylistItem);
		CORE.Input.attach("onPlaylistOrderChanged", this.update);
//		CORE.attach("onPositionChanged", this.render);
		CORE.attach("onStateChanged", this.onStateChanged);
		CORE.attach("onEndOfMediaItem", this.render);
		
		$("#playlist").get(0).addEventListener("dragenter", noOpHandler, false);
		$("#playlist").get(0).addEventListener("dragexit", noOpHandler, false);
		$("#playlist").get(0).addEventListener("dragover", noOpHandler, false);
		$("#playlist").get(0).addEventListener("drop", function(e){
			if(e.stopPropagation) e.stopPropagation();
			if(e.preventDefault) e.preventDefault();
            if(e.dataTransfer.files.length > 0){
            	var files = CORE.ResourceController.createFilesFromFile(e.dataTransfer.files);
            	self.onDropFile(files); //CORE.Input.notify("onDropFile", files);
            }
        }, true);
		
		//callback onChangeOrder noch einbauen
		$("#playlist .list").sortable({
			distance: 15,
			update: function(e, ui){
				CORE.Input.notify("onPlaylistOrderChanged");
			}
		});
		
	};
	
	var noOpHandler = function(e) {
		if(e.preventDefault) e.preventDefault();
	}
	
	/**
	 * cooler is wenn du eine render und eine update machst
	 * mit der render erstellst du nur des html und sortierst es vorher.
	 * und mit der update aktualiersierst du die elemente 
	 * (update wird dann wie ein intervall aufgerufen ... aber frag mich da vorher nochmal)
	 * allerdings is da jetzt nicht mitbedacht das man die liste auch mit der maus sortieren 
	 * kÃ¶nnen solte :(
	 */
	this.update = function(){
		
		var tempEntities = [];
		for(var i in Entities){
			var e = null;			
			for(var k = 0; k < Entities.length; k++){
				if(Entities[k].Id == $($("#playlist .list li")[i]).attr("name")){
					e = Entities[k];
				}
			}
			tempEntities[i] = e;
		}
		Entities = tempEntities;
		self.render();
	};
	
	this.render = function(){
		//sort

		$("#playlist .list").empty();
		$("#playlist .header").empty();
		for(var i in Entities){
			
			f = Entities[i];
			
			
			//debug
			//kann auch in mediaItem
			var durationToString = function(d){
				var m = 0;
				var s = (d>0) ? Math.round(d) : 0;
				while(s > 60){
					s -= 60;
					m++;
				}
				return m + ":" + ((s<10) ? "0" + s : s);
			};
			//
			
			var duration = durationToString(f.Duration);
			var playlistItemCssClasses = "playlistItem"+((!f.Buffering)? " buffered": "");
			$("#playlist .list").append("<li class='"+playlistItemCssClasses+"' name='"+f.Id+"'><span class='floatLeft songId'> "+f.Id+"</span><span class='floatLeft songName'>"+f.Name+"</span><span class='floatRight songSize'><pre>"+((Math.ceil(f.Size/100000)*10000)/100000)+" MB</pre></span><span class='floatRight songDuration'><pre>"+duration+"</pre></span></li>");
		}
		$("#playlist .header").append("<span style='text-align:right'>Current Mode = " + CurrMode + "</span>");
		$("#playlist .list li[name='"+getSelectedId()+"']").addClass('selected');
		if(CORE.Transport.isPlaying()){ 
			if(CORE.Transport.isPaused()){
				$("#playlist .list li[name='"+self.getCurr().Id+"']").removeClass('playing');
				$("#playlist .list li[name='"+self.getCurr().Id+"']").addClass('paused');
			}else{
				$("#playlist .list li[name='"+self.getCurr().Id+"']").removeClass('paused');
				$("#playlist .list li[name='"+self.getCurr().Id+"']").addClass('playing');
			}
		}else{
			$("#playlist .list li[name='"+self.getCurr().Id+"']").removeClass('playing');
			$("#playlist .list li[name='"+self.getCurr().Id+"']").removeClass('paused');
		}
	};
	
	this.onDropFile = function(files){
		for(var i in files){
			Entities.push(files[i]);
		}
		self.render(); // ===============TEMP=================

	};
	this.addItems = function(items){
		if(!items.length){
			items  = [items];
		}
		for(var i in items){
			Entities.push(items[i]);
		}
		self.render();
	};
	this.onClickPlaylistItem = function(e){
		for(var i = 0; i < $("#playlist .list li").length; i++){
			if($($("#playlist .list li")[i]).attr("name") == $(e.currentTarget).attr("name"))
				SelectedPos = i;
		}
		self.render();
	};
	
	this.onDblClickPlaylistItem = function(e){
		var items = {
		             curr: self.getCurr(),
		             next: self.getNext()
		};
		for(var i = 0; i < $("#playlist .list li").length; i++){
			if($($("#playlist .list li")[i]).attr("name") == $(e.currentTarget).attr("name"))
				Pos = SelectedPos = i;
		}
		CORE.Input.notify("playForced", items);
		self.render();
	};
	
	this.onStateChanged = function(e){
		self.render();
		
	};
	
	this.setMode = function(mode){
		if(Modes[mode]){
			CurrMode = mode;
		}
	};
	
	//######################################################//
	//     	ab hier unser playQueueIterator interface		//
	//######################################################//
	
	/**
	 * returns mediaItem of the current possition
	 * @returns mediaItem
	 */
	this.getCurr = function(){
		if(!CORE.Transport.isPlaying()){
			if(Entities[SelectedPos]){
				Pos = SelectedPos;
				return Entities[SelectedPos];
			}
		}else{
			return (Entities[Pos]) ? Entities[Pos] : false;
		}
	};
//	var getCurrentId = function return self.getCurr().Id
	var getSelectedId = function(){
		if(SelectedPos>=0)
			return Entities[SelectedPos].Id;
	};
	
	/**
	 * returns mediaItem of the next position
	 * @returns mediaItem
	 */
	this.getNext = function(){
		if(Modes[CurrMode]() >= 0){
			return (Entities[Modes[CurrMode]()]) ? Entities[Modes[CurrMode]()] : false;
		}
	};
	this.next = function(){
		Pos = SelectedPos = Modes[CurrMode]();
		return Pos;
	};
	this.previous = function(){
		Pos = SelectedPos = Modes[CurrMode](true);
		return Pos;
		
	};
	this.hasNext = function(){
		return (Entities[Modes[CurrMode]()]) ? true : false;
	};
	this.hasPrevious = function(){
		return (Entities[Modes[CurrMode](true)]) ? true : false;
		
	};
	
	this.init();
	
}